package main

import (
	"bufio"
	"fmt"
	"io"
	"net"
	"os"
	"strconv"
	"strings"
	"time"
)

func upload(conn net.Conn, params []string) {
	//文件信息
	fileName := params[0]
	fileSize, _ := strconv.Atoi(params[1])
	fmt.Println("filename:", fileName)
	fmt.Println("filesize:", fileSize)
	//循环接收文件
	file, _ := os.OpenFile("uploads/"+fileName, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 666)
	write := bufio.NewWriter(file)

	var readSize = 0
	for readSize < fileSize {
		data := make([]byte, 1024)
		n, _ := conn.Read(data)
		readSize += n
		//将每行数据写到writer中
		write.WriteString(string(data[:n]))
		write.Flush()
	}
	fmt.Println("服务端接收文件成功！")
}

//下载服务
func download(conn net.Conn, params []string) {
	fmt.Println("文件下载开始的路径:", params) //[uploads/2.png]
	//fmt.Println(params[0], reflect.TypeOf(params[0])) //uploads/2.png string
	fileName := strings.Split(params[0], "/")[1] //2.png
	//fileName := params[0]
	//fileSize, _ := strconv.Atoi(params[1])
	//fmt.Println("服务端filesize:", fileSize)

	//打开文件
	downloadFile, _ := os.Open(params[0])
	fmt.Println("downloadFile", downloadFile)

	//获取下载文件的文件名和大小
	f, _ := os.Stat(params[0])
	fileSize := f.Size()
	//fileName := f.Name()
	fmt.Println("fileSize", fileSize) //231850
	fmt.Println("fileName", fileName) //2.png
	Info := "get" + " " + fileName + " " + strconv.FormatInt(fileSize, 10)
	fmt.Println("info::", Info) //get 2.png 231850
	//先给客户端发文件信息
	conn.Write([]byte(Info))
	time.Sleep(time.Second)

	//文件内容
	reader := bufio.NewReader(downloadFile) //阅读器
	for {
		//读取文件的每一行
		lineContent, err := reader.ReadBytes('\n')
		//发送给客户端
		conn.Write(lineContent)
		if err == io.EOF {
			break
		}
	}
	fmt.Println("文件下载完成！")
}

func main() {
	//1、服务端创建套接字对象socket
	sock, err := net.Listen("tcp", "127.0.0.1:8080")
	if err != nil {
		fmt.Println("err:", err)
	}

	//关闭套接字
	defer sock.Close()

	//操作sock
	for {
		//2、等待客户端连接
		fmt.Println("server is waiting...")
		conn, err := sock.Accept()
		if err != nil {
			return
		}
		fmt.Println(conn)

		//4、接收客户端发送的姓名并转成大写再返回
		for {
			//文件上传服务
			infoBytes := make([]byte, 1024)
			n, _ := conn.Read(infoBytes)
			info := string(infoBytes[:n])
			infoSlice := strings.Split(info, " ")
			cmd := infoSlice[0]
			params := infoSlice[1:]
			fmt.Println("params:::", params)

			switch cmd {
			case "put":
				upload(conn, params)
			case "get":
				download(conn, params)

			}

		}

	}

}
